import type { ComponentStyleIdType } from '../../../types/interfaces'
import { Select } from '../../../components/select'
import { BaseModule } from '../../../lib/abstract'
import { ICON_IDS } from '../../../lib/icons/types/constants'
import { BAIDU_ADVANCE_PAGE_URL } from '../../../lib/page_handler/platform/baidu/types'
import { ToolKit } from '../../../lib/utils/toolkit'
import {
  AppStyleCollections,
  BAI_DU_BASE_URL,
  BUTTON_STYLES,
  ComponentStyleId,
  getCurrentURL,
  logger,
  MODULE_CONFIG,
} from '../../../types/constants'
import { SYMBOLS } from '../../../types/interfaces'
import { ConfigManager } from '../../config_manager'
import { StyleManager } from '../../style_manager'

// ⚠️ 需要测试是否能搜索到内容，不能搜索到内容的话，就不要添加到站点中
const COMMON_SITES = [
  { value: 'baidu.com', label: '百度' },
  { value: 'mp.weixin.qq.com', label: '微信' },
  { value: 'bilibili.com', label: '哔哩哔哩' },
  { value: 'csdn.net', label: 'CSDN' },
  { value: 'github.com', label: 'GitHub' },
  { value: 'gitee.com', label: 'Gitee' },
  { value: 'jianshu.com', label: '简书' },
  { value: 'juejin.cn', label: '掘金' },
  { value: 'zhihu.com', label: '知乎' },
  { value: 'cnblogs.com', label: '博客园' },
  { value: 'www.runoob.com', label: '菜鸟教程' },
]

interface SearchFieldConfig {
  type: 'input' | 'select' | 'radio-group'
  name: string
  label: string
  description: string
  placeholder?: string
  visible?: boolean // 控制字段是否显示
  options?: Array<{ value: string, label: string }>
  defaultValue?: string | (() => string)
  rightAddon?: {
    type: 'dropdown'
    options: Array<{ value: string, label: string }>
    onSelect: (value: string) => void
  }
  onInit?: (value: string) => void
  onChange?: (value: string) => void
}

function updateGpcParam(value: string): void {
  const gpcValue = value === '0' ? '' : SuperSearch.generateGpcParam(Number(value))
  $(`input[name="gpc"]`).val(gpcValue).trigger('change')
}

const ADVANCED_SEARCH_CONFIG: SearchFieldConfig[] = [
  {
    type: 'input',
    name: 'q6',
    label: '站内搜索',
    description: '搜索指定网站',
    placeholder: '输入网站域名，如：baidu.com',
    rightAddon: {
      type: 'dropdown',
      options: COMMON_SITES,
      onSelect: (value: string) => {
        $(`input[name="q6"]`).val(value).trigger('change')
      },
    },
  },
  {
    type: 'input',
    name: 'q1',
    label: '包含关键词',
    description: '搜索结果包含全部关键词',
    placeholder: '多个词用空格隔开',
    defaultValue: () => ToolKit.browser.url.getUrlParams('wd'),
  },
  {
    type: 'input',
    name: 'q4',
    label: '排除关键词',
    description: '搜索结果不包含关键词',
    placeholder: '多个词用空格隔开',
  },
  {
    type: 'input',
    name: 'q2',
    label: '精确匹配',
    description: '搜索结果包含完整关键词',
    placeholder: '多个词用空格隔开',
  },
  {
    type: 'input',
    name: 'q3',
    label: '任一匹配',
    description: '搜索结果包含任意一个关键词',
    placeholder: '多个词用空格隔开',
  },
  {
    type: 'select',
    name: 'lm',
    label: '时间范围',
    description: '网页发布时间',
    options: [
      { value: '0', label: '全部时间' },
      { value: '1', label: '最近一天' },
      { value: '7', label: '最近一周' },
      { value: '30', label: '最近一月' },
      { value: '360', label: '最近一年' },
    ],
    onInit: (value: string) => {
      updateGpcParam(value)
    },
    onChange: (value: string) => {
      updateGpcParam(value)
    },
  },
  {
    type: 'input',
    name: 'gpc',
    label: 'GPC',
    description: '用来构建 URL gpc 参数',
    placeholder: '',
    visible: false,
  },
  {
    type: 'select',
    name: 'ft',
    label: '文档格式',
    description: '网页格式',
    options: [
      { value: '', label: '所有网页和文件' },
      { value: 'pdf', label: '.pdf' },
      { value: 'doc', label: '.doc' },
      { value: 'xls', label: '.xls' },
      { value: 'ppt', label: '.ppt' },
      { value: 'rtf', label: '.rtf' },
      { value: 'all', label: '全部格式' },
    ],
    defaultValue: '',
  },
  {
    type: 'radio-group',
    name: 'q5',
    label: '关键词位置',
    description: '关键词出现位置',
    options: [
      { value: '', label: '任意位置' },
      { value: '1', label: '网页标题' },
      { value: '2', label: '网页URL' },
    ],
    defaultValue: '',
  },
  {
    type: 'radio-group',
    name: 'ct',
    label: '语言类型',
    description: '网页语言',
    options: [
      { value: '0', label: '全部语言' },
      { value: '1', label: '简体中文' },
      { value: '2', label: '繁体中文' },
    ],
    defaultValue: '0',
  },
]

interface Config {
  enabled?: boolean
  defaultSyntax?: string
}

export class SuperSearch extends BaseModule {
  readonly id: string = 'super_search'
  readonly styleId: string = ComponentStyleId[this.name]
  isInitialized: boolean = false
  readonly supportedPlatforms: string[] = ConfigManager.getInstance().moduleSupportedPlatforms(this.name)
  private static instance: SuperSearch
  private select: Select | null = null
  private readonly superSearchMenuId = MODULE_CONFIG.COMPONENTS.superSearch.id
  private readonly superSearchMenuSelector = MODULE_CONFIG.COMPONENTS.superSearch.selector
  private readonly advancedSelector: string = 'form'
  // 工具提示类名（来源于百度搜索）
  private readonly tooltipClass = 'tooltip_1apin'
  private readonly documentClickEventName = 'click.super-search'
  private readonly superSearchWrapperSelector: string = '.chat-input-container #right-tool > [class*="right-tool"]'
  private readonly superSearchButtonClass: string = 'super-search-btn'
  private isLoading: boolean = false

  config: Config = {
    enabled: true,
  }

  get name(): ComponentStyleIdType {
    return 'SuperSearch'
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): SuperSearch {
    if (!SuperSearch.instance) {
      SuperSearch.instance = new SuperSearch()
    }
    return SuperSearch.instance
  }

  handleCleanupCreatedElements(): void {
    this.removeSuperSearch()
    this.removeSuperSearchButton()
  }

  handleCleanupOthers(): void {
    $(document).off(this.documentClickEventName)
    $(document).off('keypress', '.advanced-search-form input')
    $(document).off('change', `${this.superSearchMenuSelector} [data-on-change]`)
  }

  /**
   * 移除超级搜索按钮
   */
  removeSuperSearchButton(): void {
    const toolItemClassList = this.getSuperSearchButtonContainerClassList()
    $(`${this.superSearchWrapperSelector} .${this.superSearchButtonClass}`).each((_, btn) => {
      $(btn).off('mouseenter mouseleave click')
    }).closest(`.${toolItemClassList.join('.')}`).remove()
  }

  core(): void {
    this.loadConfig()

    if (!this.config.enabled)
      return

    this.initializeSuperSearch()
    // 注册样式
    StyleManager.getInstance().registerStyle(this.styleId, this.getStyles(), false, true)
  }

  onToggleCallback(_id: string, checked: boolean): void {
    super.onToggleCallback(_id, checked)
  }

  /**
   * 初始化超级搜索功能
   */
  initializeSuperSearch(): void {
    this.initializeUI()
    this.bindEvents()
  }

  /**
   * 初始化UI元素
   */
  private initializeUI(): void {
    const $toolsWrapper = $(this.superSearchWrapperSelector)
    const toolItemClassList = this.getSuperSearchButtonContainerClassList()

    // 创建超级搜索按钮
    const $superSearchBtn = $(`
      <div class="${toolItemClassList.join(' ')}">
        <div class="${this.superSearchButtonClass}">
          ${this.iconService.api.icon.asSvg(ICON_IDS.other.superSearch, { size: 24 })}
        <div>
      </div>
    `)
    $superSearchBtn.on('mouseenter', e => this.toggleTooltip(e, true))
    $superSearchBtn.on('mouseleave', e => this.toggleTooltip(e, false))
    $superSearchBtn.on('click', async (e: any) => {
      // 隐藏提示
      this.toggleTooltip(e, false)
      // 显示菜单
      await this.showSyntaxMenu(e)
      // 挂载组件
      this.select?.mount($(`${this.superSearchMenuSelector}`))
      // 初始化表单字段
      this.handleFormFieldInit()
    })

    if (!$toolsWrapper || $toolsWrapper.length === 0) {
      logger.warn(`[${this.name}] 未找到工具容器元素`)
      return
    }

    $toolsWrapper.append($superSearchBtn)
  }

  /**
   * 获取超级搜索按钮容器类名
   */
  getSuperSearchButtonContainerClassList(): string[] {
    const $toolsWrapper = $(this.superSearchWrapperSelector)
    const $toolItem = $toolsWrapper.find('[class*="tooltip-wrapper"]')
    return ToolKit.ui.element.parseElementClassList($toolItem)
  }

  /**
   * 显示工具提示
   */
  private toggleTooltip(e: any, show: boolean): void {
    const $button = $(e.currentTarget)

    let $tooltip = $button.find(`.${this.tooltipClass}`)

    if (!show) {
      $tooltip?.remove()
      return
    }

    if ($tooltip && $tooltip.length > 0) {
      return
    }

    $tooltip = $(`
      <div class="${this.tooltipClass}">
        <span>高级搜索助手，支持：intitle、site、filetype等专业搜索语法</span>
      </div>`)
    $button.append($tooltip)
  }

  /**
   * 显示语法选择菜单
   */
  private async showSyntaxMenu(e: JQuery.ClickEvent): Promise<void> {
    e.preventDefault()
    e.stopPropagation()

    let $menu = $(this.superSearchMenuSelector)

    if ($menu && $menu.length > 0) {
      this.removeSuperSearch()
      return
    }

    const menuDoc = await this.fetchAdvancedPage()
    const advancedForm = menuDoc.querySelector(this.advancedSelector)

    if (!advancedForm) {
      logger.warn(`[${this.name}] 未找到高级搜索表单元素`)
      return
    }

    const cloneAdvancedForm = advancedForm.cloneNode(true) as HTMLElement
    this.hideAdvancedFormElements(cloneAdvancedForm)

    $menu = $(`
      <div id="${this.superSearchMenuId}">
        ${this.advancedFormTemplate}
        <div class="search-action-buttons">
          <button class="btn ${BUTTON_STYLES.primary.className} bd-search-btn">
            <span class="bd-icon-search"></span> 百度一下
          </button>
          <button class="btn ${BUTTON_STYLES.secondary.className} bd-close-btn">
            <span class="bd-icon-close"></span> 关闭
          </button>
        </div>
      </div>
    `)

    $('body #content_right').after($menu)
  }

  private get advancedFormTemplate(): string {
    return `
      <form class="advanced-search-form" action="${BAI_DU_BASE_URL}/s" target="_blank">
        <div class="form-content">
          ${ADVANCED_SEARCH_CONFIG.map(config =>
            this.renderFormField(config),
          ).join('')}
        </div>
      </form>
    `
  }

  private renderFormField(config: SearchFieldConfig): string {
    const inputId = `${config.name}-${config.type}`
    const visibleStyle = config.visible === false ? 'style="display:none"' : ''

    return `
    <div class="search-field" ${visibleStyle}>
      <label for="${inputId}" class="field-label" title="${config.description}">
        ${config.label}
      </label>
      ${this.renderControl(config, inputId)}
    </div>
  `
  }

  private renderControl(config: SearchFieldConfig, inputId: string): string {
    const defaultValue = this.getDefaultValue(config)

    switch (config.type) {
      case 'input':
        return `
          ${config.rightAddon?.type === 'dropdown'
              ? `
                <div class="dropdown-wrapper">
                  ${this.renderSelect(config, defaultValue)}
                  ${this.renderInput(config, defaultValue, inputId)}
                </div>`
              : `${this.renderInput(config, defaultValue, inputId)}`
          }
      `

      case 'select':
        return `
          <select 
            id="${inputId}" 
            name="${config.name}" 
            class="search-select" 
            ${config.onInit ? `data-on-init="${config.name}"` : ''}
            ${config.onChange ? `data-on-change="${config.name}"` : ''}>
            ${config.options?.map(opt =>
              `<option value="${opt.value}" ${opt.value === defaultValue ? 'selected' : ''}>${opt.label}</option>`,
            ).join('')}
          </select>
      `

      case 'radio-group':
        return `
          <div class="radio-group">
            ${config.options?.map(opt => `
              <label class="radio-label">
                <input 
                  type="radio" 
                  name="${config.name}" 
                  value="${opt.value}"
                  ${opt.value === defaultValue ? 'checked' : ''}
                  autocomplete="off"
                >
                ${opt.label}
              </label>
            `).join('')}
          </div>
      `
    }
  }

  renderInput(config: SearchFieldConfig, defaultValue: string, id: string): string {
    return `
      <input 
        type="text" 
        id="${id}"
        value="${config.visible !== false ? defaultValue : ''}"
        name="${config.name}" 
        placeholder="${config.placeholder || ''}"
        autocomplete="off"
        class="search-input"
        ${config.onInit ? `data-on-init="${config.name}"` : ''}
        ${config.onChange ? `data-on-change="${config.name}"` : ''}
      >
    `
  }

  renderSelect(config: SearchFieldConfig, defaultValue: string): string {
    this.select = new Select({
      id: 'q6-select',
      label: '可选择',
      selectedValue: defaultValue,
      labelTextPosition: 'left',
      options: config.rightAddon?.options || [],
      clearable: true,
      showPlaceholder: true,
      placeholder: '内置域名',
      onChange: (value: string | undefined) => {
        $(`input[name="q6"]`).val(value || '').trigger('change')
      },
    })
    return this.select.render()
  }

  /**
   * 获取输入框的默认值
   */
  getDefaultValue(config: SearchFieldConfig): string {
    let defaultValue: string | null | undefined

    // 1. 优先从当前页面URL解析
    const urlParams = ToolKit.browser.url.parseUrlParams(getCurrentURL())
    defaultValue = urlParams[config.name] || null

    if (defaultValue !== null)
      return defaultValue

    // 2. 使用配置中的默认值
    defaultValue = typeof config.defaultValue === 'function' ? config.defaultValue() : config.defaultValue

    return defaultValue || ''
  }

  /**
   * 获取高级搜索页面内容
   */
  private async fetchAdvancedPage(): Promise<Document> {
    const url = BAIDU_ADVANCE_PAGE_URL

    // 静默跳过并发请求
    if (this.isLoading) {
      return new Promise(() => {}) // 返回永远pending的Promise
    }

    return new Promise((resolve) => {
      this.isLoading = true

      $.ajax({
        url,
        dataType: 'html',
        timeout: 8000,
        success: (html) => {
          try {
            const parser = new DOMParser()
            const doc = parser.parseFromString(html, 'text/html')

            // 验证内容有效性
            if ($('form', doc).length > 0) {
              resolve(doc)
            }
            else {
              logger.notice(`[${this.name}] ${SYMBOLS.STATUS.WARNING} 高级搜索页面内容无效`)
              resolve(document) // 返回空文档避免中断流程
            }
          }
          catch (e: any) {
            logger.warn(`[${this.name}] 解析失败: ${e.message}`)
            resolve(document)
          }
        },
        error: (_xhr, status, _error) => {
          console.error(`[${this.name}] 请求中止: ${status}`)
          resolve(document) // 返回空文档
        },
        complete: () => {
          this.isLoading = false
        },
      })
    })
  }

  /**
   * 隐藏高级搜索相关元素
   */
  hideAdvancedFormElements(form: HTMLElement): void {
    // 隐藏搜索结果显示条数
    $(form).find('tr:contains("搜索结果显示条数")').hide()
  }

  /**
   * 绑定事件
   */
  bindEvents(): void {
    this.handleFormFieldChange()
    this.handleFormEvent()
    this.handleClickSearchButton()
    this.handleClickCloseButton()
  }

  /**
   * 处理表单字段初始化事件
   */
  handleFormFieldInit(): void {
    $(`${this.superSearchMenuSelector} [data-on-init]`).each((_index, el) => {
      const $field = $(el)
      const fieldName = $field.attr('data-on-init')!
      const value = $field.val() as string

      // 查找配置并触发回调
      const config = ADVANCED_SEARCH_CONFIG.find(c => c.name === fieldName)
      config?.onInit?.(value)
    })
  }

  /**
   * 处理表单字段变化事件
   */
  handleFormFieldChange(): void {
    $(document).on('change', `${this.superSearchMenuSelector} [data-on-change]`, (e) => {
      const $field = $(e.currentTarget)

      const fieldName = $field.attr('data-on-change')!
      const value = $field.val() as string

      // 查找配置并触发回调
      const config = ADVANCED_SEARCH_CONFIG.find(c => c.name === fieldName)
      config?.onChange?.(value)
    })
  }

  /**
   * 处理表单事件
   */
  handleFormEvent(): void {
    $(document).on('keypress', '.advanced-search-form input', (e) => {
      if (e.key === 'Enter') {
        e.preventDefault() // 阻止表单提交
        e.stopPropagation() // 阻止事件冒泡
      }
    })
  }

  /**
   * 处理搜索按钮点击事件（使用事件委托）
   */
  private handleClickSearchButton(): void {
    $(document).on(this.documentClickEventName, '.bd-search-btn', (_e) => {
      const searchForm = document.querySelector(`${this.superSearchMenuSelector} ${this.advancedSelector}`) as HTMLFormElement

      if (!searchForm) {
        logger.error(`[${this.name}] 未找到搜索表单元素`)
        return
      }

      searchForm.submit()
    })
  }

  /**
   * 处理关闭按钮点击事件（使用事件委托）
   */
  private handleClickCloseButton(): void {
    $(document).on(this.documentClickEventName, '.bd-close-btn', this.removeSuperSearch.bind(this))
  }

  /**
   * 移除超级搜索菜单
   */
  removeSuperSearch(): void {
    this.select?.destroy()
    this.select = null
    $(this.superSearchMenuSelector).remove()
  }

  /**
   * 生成百度搜索的时间范围参数
   * @param days 天数（1=最近一天，7=最近一周，30=最近一月，360=最近一年）
   */
  static generateGpcParam(days: number): string {
    const now = Math.floor(Date.now() / 1000) // 当前时间戳（秒）
    const start = now - (days * 86400) // 开始时间戳（days天前）
    return `stf=${start},${now}|stftype=1`
  }

  applyConfig(config: Partial<Config>): void {
    super.updateConfig(config)

    this.initializeSuperSearch()

    logger.info(`[${this.name}] Config updated and apply`, this.config)
  }

  getStyles(): string {
    return `
.chat-input-container #right-tool > [class*="right-tool"] {
  display: flex;
  align-items: center;
}

${this.superSearchMenuSelector} { 
  width: ${AppStyleCollections.Search.value.ITEM_DYNAMIC_WIDTH} !important;
  background: var(${this.themeVarService.search.resultItem.background}) !important;
  border-radius: ${this.themeVarService.search.resultItem.borderRadius} !important;
  margin: 15px 0 0 15px;
  padding: 16px;
  
  .advanced-search-form {
    .form-content {
      display: flex;
      flex-direction: column;
      gap: 10px;
      justify-content: space-between;
      
      .search-field {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: 5px;
        
        .field-label {
          display: flex;
          flex-direction: column;
          font-size: 14px;
          font-weight: 600;
          color: var(${this.themeVarService.search.default.text}) !important;
        }
        
        .search-input {
          ${this.stylesService.input.default}
        }
        
        .search-select {
          ${this.stylesService.select.default}
        }
          
        .dropdown-wrapper {
          display: flex;
          flex-direction: row;
          align-items: center;
          gap: 5px;
        }
      }
      
      .search-input {
        min-width: 210px;
      }

      .radio-group {
        display: flex;
        gap: 10px;
        flex-wrap: wrap;
        
        .radio-label {
          display: flex;
          align-items: center;
          cursor: pointer;
          gap: 5px;
        }
      }
    }
  }
  
  .search-action-buttons {
    display: flex;
    gap: 16px;
    flex-direction: row;
    align-items: center;
    justify-content: flex-end;
    
    .bd-icon-search::before {
      content: '${SYMBOLS.UI.SEARCH_MINIMAL}';
      font-size: 19px;
      line-height: 1;
    }
    
    .bd-icon-close::before {
      content: '${SYMBOLS.UI.CLOSE}';
    }
    
    .bd-icon-search,
    .bd-icon-close {
      margin-right: 6px;
      font-size: 14px;
    }
  }
}
`
  }
}
